package storage.record;

import storage.file.Block;
import storage.tx.Transaction;

public class RecordFile {
	private TableInfo ti;
	private Transaction tx;
	private String filename;
	private RecordPage rp;
	private int currentblknum;
	
	public RecordFile(TableInfo ti, Transaction tx){
		this.ti = ti;
		this.tx = tx;
		filename = ti.fileName();
		if(tx.size(filename) == 0)
			appendBlock();
		moveTo(0);
	}
	
	public void close(){
		rp.close();
	}
	
	public void beforeFirst(){
		moveTo(0);
	}
	
	public boolean next(){
		while(true){
			if (rp.next())
				return true;
			if (atLastBlock())
				return false;
			moveTo(currentblknum + 1);
		}
	}

	public int getInt(String fldname){
		return rp.getInt(fldname);
	}
	
	public String getString(String fldname){
		return rp.getString(fldname);
	}
	
	public void setInt(String fldname, int val){
		rp.setInt(fldname, val);
	}
	
	public void setString(String fldname, String val){
		rp.setString(fldname, val);
	}
	
	public void delete(){
		rp.delete();
	}
	
	public void insert(){
		while(!rp.insert()){
			if(atLastBlock())
				appendBlock();
			moveTo(currentblknum + 1);
		}
	}
	
	public void moveToRid(RID rid){
		moveTo(rid.blocknum());
		rp.moveToID(rid.id());
	}
	
	public RID currentRid(){
		int id = rp.currentID();
		return new RID(currentblknum, id);
	}
	
	private void moveTo(int blknum){
		if (rp != null)
			rp.close();
		currentblknum = blknum;
		Block blk = new Block(filename, currentblknum);
		rp = new RecordPage(blk, ti, tx);
	}
	
	private boolean atLastBlock(){
		return currentblknum == tx.size(filename) - 1;
	}
	
	private void appendBlock(){
		RecordFormatter fmtr = new RecordFormatter(ti);
		tx.append(filename, fmtr);
	}
}
